001 /*
002 * Copyright 2005 Stephen J. McConnell
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.tools.tasks;
020
021 import java.io.File;
022
023 import net.dpml.lang.Version;
024
025 import net.dpml.library.Resource;
026 import net.dpml.library.Type;
027
028 import org.apache.tools.ant.BuildException;
029 import org.apache.tools.ant.taskdefs.Jar;
030 import org.apache.tools.ant.taskdefs.Manifest;
031 import org.apache.tools.ant.taskdefs.ManifestException;
032 import org.apache.tools.ant.taskdefs.Copy;
033
034 /**
035 * Execute all plugins relative to the current build phase.
036 *
037 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
038 * @version 1.1.1
039 */
040 public class JarTask extends GenericTask
041 {
042 /**
043 * Constant key for the manifest main class value.
044 */
045 public static final String JAR_MAIN_KEY = "project.jar.main.class";
046
047 /**
048 * Constant key for the manifest classpath value.
049 */
050 public static final String JAR_CLASSPATH_KEY = "project.jar.classpath";
051
052 private File m_source;
053 private File m_destination;
054
055 /**
056 * Task initialization.
057 */
058 public void init()
059 {
060 if( !isInitialized() )
061 {
062 super.init();
063 }
064 }
065
066 /**
067 * Set the src directory.
068 * @param source the source directory
069 */
070 public void setSrc( File source )
071 {
072 if( source.isDirectory() )
073 {
074 m_source = source;
075 }
076 else
077 {
078 final String error =
079 "Jar task src must be a directory.";
080 throw new BuildException( error, getLocation() );
081 }
082 }
083
084 /**
085 * Set the destination file.
086 * @param destination the destination file
087 */
088 public void setDest( File destination )
089 {
090 m_destination = destination;
091 }
092
093 private File getSource()
094 {
095 if( null == m_source )
096 {
097 final String error =
098 "Missing 'src' attribute in jar task.";
099 throw new BuildException( error, getLocation() );
100 }
101 else
102 {
103 return m_source;
104 }
105 }
106
107 private File getDestination()
108 {
109 if( null == m_destination )
110 {
111 final String error =
112 "Missing 'dest' attribute in jar task.";
113 throw new BuildException( error, getLocation() );
114 }
115 else
116 {
117 return m_destination;
118 }
119 }
120
121 /**
122 * Execute the task.
123 */
124 public void execute()
125 {
126 File source = getSource();
127 if( !source.exists() )
128 {
129 return;
130 }
131 File jar = createJarFile( source );
132 checksum( jar );
133 asc( jar );
134 }
135
136 private File createJarFile( final File classes )
137 {
138 final File temp = getTempFile();
139
140 final Jar jar = (Jar) getProject().createTask( "jar" );
141 jar.setTaskName( getTaskName() );
142 jar.setDestFile( temp );
143 jar.setBasedir( classes );
144 jar.setIndex( true );
145 addManifest( jar );
146 jar.init();
147 jar.execute();
148
149 File dest = getDestination();
150 final File dir = dest.getParentFile();
151 mkDir( dir );
152
153 final Copy copy = (Copy) getProject().createTask( "copy" );
154 copy.setTaskName( getTaskName() );
155 copy.setFile( temp );
156 copy.setTofile( dest );
157 copy.init();
158 copy.execute();
159
160 return dest;
161 }
162
163 private File getTempFile()
164 {
165 final File target = getContext().getTargetDirectory();
166 final String path = getTempFilename();
167 return new File( target, path );
168 }
169
170 private String getTempFilename()
171 {
172 Resource resource = getResource();
173 String name = resource.getName();
174 Version version = resource.getDecimalVersion();
175 if( null != version )
176 {
177 return name + "-" + version.toString() + ".jar";
178 }
179 else
180 {
181 String spec = resource.getVersion();
182 return name + "-" + spec + ".jar";
183 }
184 }
185
186 private Type getType()
187 {
188 Resource resource = getResource();
189 return resource.getType( "jar" );
190 }
191
192 private void addManifest( final Jar jar )
193 {
194 try
195 {
196 Type type = getType();
197 Resource resource = getResource();
198
199 final Manifest manifest = new Manifest();
200 final Manifest.Section main = manifest.getMainSection();
201
202 String publisher = resource.getProperty( "project.publisher.name" );
203 if( null != publisher )
204 {
205 addAttribute( main, "Created-By", publisher );
206 }
207
208 addAttribute( main, "Built-By", System.getProperty( "user.name" ) );
209 final String classpath = getProject().getProperty( JAR_CLASSPATH_KEY );
210 if( null != classpath )
211 {
212 addAttribute( main, "Class-Path", classpath );
213 }
214
215 final String mainClass = resource.getProperty( JAR_MAIN_KEY );
216 if( null != mainClass )
217 {
218 addAttribute( main, "Main-Class", mainClass );
219 }
220
221 addAttribute( main, "Extension-Name", getResource().getResourcePath() );
222 String specificationVendor = resource.getProperty( "project.specification.vendor" );
223 if( null != specificationVendor )
224 {
225 addAttribute( main, "Specification-Vendor", specificationVendor );
226 }
227
228 String version = resource.getProperty( "project.specification.version" );
229 if( null != version )
230 {
231 addAttribute( main, "Specification-Version", version );
232 }
233
234 String implementationVendor = resource.getProperty( "project.implementation.vendor" );
235 if( null != implementationVendor )
236 {
237 addAttribute( main, "Implementation-Vendor", implementationVendor );
238 }
239
240 String implementationVendorID = resource.getProperty( "project.implementation.vendor-id" );
241 if( null != implementationVendorID )
242 {
243 addAttribute( main, "Implementation-Vendor-Id", implementationVendorID );
244 }
245
246 final Version spec = resource.getDecimalVersion();
247 if( null != spec )
248 {
249 String implementationVersion = spec.toString();
250 addAttribute( main, "Implementation-Version", implementationVersion );
251 }
252
253 jar.addConfiguredManifest( manifest );
254 }
255 catch( Throwable e )
256 {
257 throw new BuildException( e );
258 }
259 }
260
261 private void addAttribute(
262 final Manifest.Section section, final String name, final String value )
263 throws ManifestException
264 {
265 final Manifest.Attribute attribute = new Manifest.Attribute( name, value );
266 section.addConfiguredAttribute( attribute );
267 }
268 }